package com.zhaoyue.study.concurrency.example.listsum;

import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created with IntelliJ IDEA.
 * User: zhaoyue
 * Date: 2016/9/7
 * Time: 14:03
 * 淘宝面试题
 * 有一个很大的整数list,需求这个list中所有整数的和
 * 写一个充分利用多核cpu的做法
 */
public class CountListIntegerSum {

    private long sum;
    private CyclicBarrier cyclicBarrier;
    private List<Integer> list;
    private int threadCounts;

    public CountListIntegerSum(List<Integer> list,int threadCounts){
        this.list = list;
        this.threadCounts = threadCounts;
    }

    public long getIntegerSum(){
        ExecutorService executorService = Executors.newFixedThreadPool(threadCounts);
        int len = list.size() / threadCounts;
        if(len==0){
            threadCounts = list.size();
            len = list.size() / threadCounts;
        }

        cyclicBarrier = new CyclicBarrier(threadCounts + 1);
        for (int i = 0; i < threadCounts; i++) {
            if(i == threadCounts -1){
                executorService.execute(new SubIntegerSumTask(list.subList(i*len,list.size())));
            }else {
                executorService.execute(new SubIntegerSumTask(list.subList(i*len,len*(i+1)>list.size()?list.size():len*(i+1))));
            }
        }

        try{
            cyclicBarrier.await();
        }catch (Exception e){
            e.printStackTrace();
        }

        executorService.shutdown();
        return sum;
    }


    public class SubIntegerSumTask implements Runnable{

        private List<Integer> subList;
        public SubIntegerSumTask(List<Integer> subList){
            this.subList = subList;
        }

        @Override
        public void run() {

            long subSum = 0;
            for(Integer i : subList){
                subSum += i;
            }

            synchronized (CountListIntegerSum.this){
                sum += subSum;
            }

            try{
                cyclicBarrier.await();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) {

        List<Integer> list = Lists.newArrayList();
        int threadCounts = 10;//采用的线程数
        //生成的List数据
        for (int i = 1; i <= 1000000; i++) {
            list.add(i);
        }
        CountListIntegerSum countListIntegerSum=new CountListIntegerSum(list,threadCounts);
        long sum=countListIntegerSum.getIntegerSum();
        System.out.println("List中所有整数的和为:"+sum);
    }

}
